/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.tbp.persitence.dao.impl;

import br.com.tbp.exception.PersistenciaException;
import br.com.tbp.model.domain.financeiro.Lancamento;
import br.com.tbp.model.domain.financeiro.TipoConta;
import br.com.tbp.persitence.GerenciadorDeConexao;
import br.com.tbp.persitence.GerenciadorDeQuery;
import br.com.tbp.persitence.dao.LancamentoDao;
import br.com.tbp.utils.DateUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Diego
 */
public class LancamentoDaoImpl implements LancamentoDao {

    private Connection conn = null;
    private PreparedStatement pr = null;
    private ResultSet rs = null;

    public void registrar(Lancamento lc) throws PersistenciaException {
        if (lc == null) {
            throw new PersistenciaException("Não foi informado a lançamento a registrar.");
        }
        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("lancamento.insert"));
            pr.setDate(1, DateUtils.dataObjetoParaDataBancoDeDados(lc.getData()));
            pr.setString(2, lc.getDescricao());
            pr.setString(3, lc.getTipo().name());
            pr.setDouble(4, lc.getValor());
            pr.setDouble(5, lc.getDesconto());
            pr.setDouble(6, lc.getTotal());
            pr.setLong(7, lc.getConta() != null ? lc.getConta().getId() : 0);
            pr.executeUpdate();

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível registrar o lançamento.");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr);
        }
    }

    public boolean estornar(Lancamento lc) throws PersistenciaException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<Lancamento> pesquisar(int mes, int ano) throws PersistenciaException {
        List<Lancamento> lista = new ArrayList<Lancamento>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("lancamento.select.mesano"));
            pr.setInt(1, mes);
            pr.setInt(2, ano);
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Lancamento lc = this.criarLancamento(rs);
                    lista.add(lc);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar os lançamentos de: ").append(mes).append("/").append(ano);
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }

    private Lancamento criarLancamento(ResultSet rs) throws PersistenciaException {
        Lancamento lc = null;
        try {
            lc = new Lancamento(rs.getLong("id_lancamento"));
            lc.setData(DateUtils.dataBancoDeDadosParaDataObjeto(rs.getDate("data")));
            lc.setDescricao(rs.getString("descricao"));
            lc.setTipo(TipoConta.valueOf(rs.getString("tipo")));
            lc.setTotal(new Double(rs.getDouble("total")));
        } catch (SQLException sqlex) {
            StringBuilder msg = new StringBuilder("Não foi possível obter os dados do lançamento.");
            msg.append("\nMotivo: ").append(sqlex.getMessage());
            throw new PersistenciaException(msg.toString());
        }
        return lc;
    }

    public List<Lancamento> pesquisarPor(String descricao) throws PersistenciaException {
        List<Lancamento> lista = new ArrayList<Lancamento>();

        try {
            conn = GerenciadorDeConexao.abreConexao();
            pr = conn.prepareStatement(GerenciadorDeQuery.getQuery("lancamento.select.descricao"));
            pr.setString(1, descricao+"%");
            rs = pr.executeQuery();

            if (rs != null) {
                while (rs.next()) {
                    Lancamento lc = this.criarLancamento(rs);
                    lista.add(lc);
                }
            }

        } catch (SQLException exc) {
            StringBuilder msg = new StringBuilder("Não foi possível pesquisar os lançamentos");
            msg.append("\nMotivo: ").append(exc.getMessage());
            throw new PersistenciaException(msg.toString());
        } finally {
            GerenciadorDeConexao.fechaConexao(conn, pr, rs);
        }
        return lista;
    }
}
